package com.his.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.errorprone.annotations.RestrictedApi;
import com.google.errorprone.annotations.Var;
import com.his.commons.core.dto.PageInfo;
import com.his.commons.core.exception.HisException;
import com.his.commons.core.util.TimeUtil;
import com.his.commons.web.util.WebBeanUtils;
import com.his.controller.form.*;
import com.his.controller.info.*;
import com.his.mapper.DisagnosisRoomMapper;
import com.his.mapper.ScheduleMapper;
import com.his.model.DisagnosisRoom;
import com.his.model.Schedule;
import com.his.model.UserInfo;
import com.his.mapper.UserInfoMapper;
import com.his.service.*;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.his.util.Md5Util;
import com.his.util.StaticDataUtil;
import com.his.util.StringToTrimUtil;
import org.apache.catalina.User;
import org.springframework.http.HttpRequest;
import org.springframework.stereotype.Service;
import sun.security.provider.MD5;

import javax.annotation.Resource;
import java.io.UnsupportedEncodingException;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Pattern;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author 梅津铧
 * @since 2022-03-22
 */
@Service
public class UserInfoServiceImpl extends ServiceImpl<UserInfoMapper, UserInfo> implements UserInfoService {

    @Resource
    private UserInfoMapper userInfoMapper;
    @Resource
    private DisagnosisRoomService disagnosisRoomService;
    @Resource
    private DisagnosisRoomMapper disagnosisRoomMapper;
    @Resource
    private DepartmentService departmentService;
    @Resource
    private RoleService roleService;
    @Resource
    private ScheduleService scheduleService;
    @Resource
    private ScheduleMapper scheduleMapper;

    /**
     * 注册员工
     *
     * @param newUserForm
     */
    @Override
    public boolean increaseUser(NewUserForm newUserForm) throws HisException{
        //判断是否含有空字符等
        if(!StringToTrimUtil.StringToTrim(newUserForm.getUserRoleName())) throw new HisException("请确定该员工的角色",500);

        //判断角色是否存在
        List<RoleInfo> roleInfos = roleService.obtainOneRole(newUserForm.getUserRoleName());
        if(null == roleInfos) throw new HisException("该角色不存在",500);
        boolean role = false;
        for (RoleInfo roleInfo : roleInfos) {
            if(roleInfo.getRoleName().equals(newUserForm.getUserRoleName())){
                role = true;
            }
        }
        if(!role) throw new HisException("该角色不存在",500);
        //校验参数
        if(!StringToTrimUtil.StringToTrim(newUserForm.getUserName()) | !StringToTrimUtil.StringToTrim(newUserForm.getUserPassword())  |
                !StringToTrimUtil.StringToTrim(newUserForm.getUserGender()) | !StringToTrimUtil.StringToTrim(newUserForm.getUserPhone()) |
                !StringToTrimUtil.StringToTrim(newUserForm.getUserIdCard())){
            throw new HisException("请输入正确的信息",500);
        }
        //员工是否存在
        UserInfo userByIDcard = userInfoMapper.selectOne(new QueryWrapper<UserInfo>().eq("user_Id_card", newUserForm.getUserIdCard()));
        if(userByIDcard != null) throw new HisException("该员工已存在",500);

        if(!newUserForm.getUserRoleName().equals("管理员") && !newUserForm.getUserRoleName().equals("收费员")){
            if(!StringToTrimUtil.StringToTrim(newUserForm.getUserDepartment())){
                throw new HisException("请输入科室信息",500);
            }
            if(newUserForm.getDepartmentId()<=0) throw new HisException("科室id必须大于0",500);
            if(!newUserForm.getUserDepartment().contains("科")) throw new HisException("科室名称要规范",500);

            //科室是否存在
            DepartmentInfo departmentInfo = departmentService.obtainByCondition(newUserForm.getUserDepartment());
            if(null == departmentInfo | departmentInfo.getDepartmentId()!=newUserForm.getDepartmentId()) throw new HisException("该科室信息有误",500);
            if(departmentInfo.getDepartmentState().equals("是") ) {
                //诊室是否存在
                if(null == newUserForm.getDisagnosisId() | null==newUserForm.getUserDisagnosisRoom())
                    throw new HisException("该科室有下属诊室，请确定诊室信息",500);
                if(!StringToTrimUtil.StringToTrim(newUserForm.getUserDisagnosisRoom())) throw new HisException("该科室有下属诊室，请确定诊室信息",500);;
                List<DisagnosisRoomInfo> disagnosisRoomInfos = disagnosisRoomService.obtainDisRoom(newUserForm.getDepartmentId());
                if(null == disagnosisRoomInfos | disagnosisRoomInfos.size()==0) throw new HisException("获取下属诊室信息失败",500);
                boolean dis = false;
                for (DisagnosisRoomInfo disagnosisRoomInfo : disagnosisRoomInfos) {
                    if(disagnosisRoomInfo.getDisagnosisId() == newUserForm.getDisagnosisId() && disagnosisRoomInfo.getDisagnosisName().equals(newUserForm.getUserDisagnosisRoom())){
                        dis = true;
                    }
                }
                if(!dis) throw new HisException("该诊室不存在",500);
            }else{
                if(null != newUserForm.getDisagnosisId() ) throw new HisException("该科室无下属诊室",500);
                if(null != newUserForm.getUserDisagnosisRoom()) throw new HisException("该科室无下属诊室",500);
            }
        }

        //注册员工
        UserInfo userInfo = WebBeanUtils.copyObject(newUserForm, UserInfo.class);
        userInfo.setUserCreatetime(TimeUtil.getTimeString());
        try {
            userInfo.setUserPassword(Md5Util.EncoderByMd5(newUserForm.getUserPassword()));
        } catch (NoSuchAlgorithmException e) {
            throw new HisException("密码加密失败",500);
        } catch (UnsupportedEncodingException e) {
            throw new HisException("密码加密失败",500);
        }
        System.out.println(userInfo);
        int insert = userInfoMapper.insert(userInfo);
        if(insert<=0) throw new HisException("注册员工失败，请稍后重试",500);

        //生成排班信息记录
        if(!newUserForm.getUserRoleName().equals("管理员") | !newUserForm.getUserRoleName().equals("收费员")){
            NewScheduleForm newScheduleForm = new NewScheduleForm();
            newScheduleForm.setDepartmentId(userInfo.getDepartmentId());
            newScheduleForm.setDisagnosisId(userInfo.getDisagnosisId());
            newScheduleForm.setScheduleUserId(userInfo.getUserJobNum());
            newScheduleForm.setScheduleUserName(userInfo.getUserName());
            boolean b = scheduleService.increaseSchedules(newScheduleForm);
            if(!b) throw new HisException("排班信息记录生成失败",500);
        }
        return true;
    }

    /**
     * 修改权限
     *
     * @param newUserForm
     */
    @Override
    public boolean modifyUser(ModifyUserForm newUserForm) throws HisException {
        //判断是否含有空字符等
        if(!StringToTrimUtil.StringToTrim(newUserForm.getUserRoleName())) throw new HisException("请确认员工的角色信息",500);

        //判断角色是否存在
        List<RoleInfo> roleInfos = roleService.obtainOneRole(newUserForm.getUserRoleName());
        if(null == roleInfos) throw new HisException("该角色不存在",500);
        boolean role = false;
        for (RoleInfo roleInfo : roleInfos) {
            if(roleInfo.getRoleName().equals(newUserForm.getUserRoleName())){
                role = true;
            }
        }
        if(!role) throw new HisException("该角色不存在",500);

        //员工是否存在
        UserInfo userByIDcard = userInfoMapper.selectOne(new QueryWrapper<UserInfo>().eq("user_Id_card", newUserForm.getUserIdCard()));
        if(userByIDcard == null) throw new HisException("该员工不存在",500);

        if(!newUserForm.getUserRoleName().equals("管理员") && !newUserForm.getUserRoleName().equals("收费员")){
            if(null==newUserForm.getDepartmentId() | null==newUserForm.getUserDepartment()) throw new HisException("请输入科室信息",500);
            if(!StringToTrimUtil.StringToTrim(newUserForm.getUserName()) |
                    !StringToTrimUtil.StringToTrim(newUserForm.getUserGender()) | !StringToTrimUtil.StringToTrim(newUserForm.getUserPhone()) |
                    !StringToTrimUtil.StringToTrim(newUserForm.getUserDepartment())| !StringToTrimUtil.StringToTrim(newUserForm.getUserIdCard())){
                throw new HisException("请输入正确的信息",500);
            }
            if(newUserForm.getDepartmentId()<=0) throw new HisException("id必须大于0",500);
            if(!newUserForm.getUserDepartment().contains("科")) throw new HisException("科室名称要规范",500);

            //科室、诊室是否存在
            DepartmentInfo departmentInfo = departmentService.obtainByCondition(newUserForm.getUserDepartment());
            if(null == departmentInfo | departmentInfo.getDepartmentId()!=newUserForm.getDepartmentId()) throw new HisException("该科室信息有误",500);
            if(departmentInfo.getDepartmentState().equals("是") ) {
                //诊室是否存在
                if(!StringToTrimUtil.StringToTrim(String.valueOf(newUserForm.getDisagnosisId())) | !StringToTrimUtil.StringToTrim(newUserForm.getUserDisagnosisRoom()))
                    throw new HisException("该科室有下属诊室，请确定诊室信息",500);
                List<DisagnosisRoomInfo> disagnosisRoomInfos = disagnosisRoomService.obtainDisRoom(newUserForm.getDepartmentId());
                if(null == disagnosisRoomInfos | disagnosisRoomInfos.size()==0) throw new HisException("获取下属诊室信息失败",500);
                boolean dis = false;
                for (DisagnosisRoomInfo disagnosisRoomInfo : disagnosisRoomInfos) {
                    if(disagnosisRoomInfo.getDisagnosisId() == newUserForm.getDisagnosisId() && disagnosisRoomInfo.getDisagnosisName().equals(newUserForm.getUserDisagnosisRoom())){
                        dis = true;
                    }
                }
                if(!dis) throw new HisException("该诊室不存在",500);
            }else{
                if(null != newUserForm.getDisagnosisId() ) throw new HisException("该科室无下属诊室",500);
                if(null != newUserForm.getUserDisagnosisRoom()) throw new HisException("该科室无下属诊室",500);
            }
        }

        //更新员工信息
        UserInfo userInfo = WebBeanUtils.copyObject(newUserForm, UserInfo.class);
        if(!newUserForm.getUserRoleName().equals("管理员") && !newUserForm.getUserRoleName().equals("收费员")){
            if(null!=newUserForm.getDepartmentId() && null!=newUserForm.getUserDepartment() && null==newUserForm.getDisagnosisId() && null==newUserForm.getUserDisagnosisRoom()){
                System.out.println(111);
                userInfo.setDisagnosisId(0);
                userInfo.setUserDisagnosisRoom(" ");
            }
        }
        if(newUserForm.getUserPassword()!=null && StringToTrimUtil.StringToTrim(newUserForm.getUserPassword())){
            System.out.println(newUserForm.getUserPassword());
            int length = StringToTrimUtil.StringToString(newUserForm.getUserPassword()).length();
            if(length>=6 && length<=10){
                //对密码加密
                try {
                    userInfo.setUserPassword(Md5Util.EncoderByMd5(newUserForm.getUserPassword()));
                } catch (NoSuchAlgorithmException e) {
                    throw new HisException("密码加密失败",500);
                } catch (UnsupportedEncodingException e) {
                    throw new HisException("密码加密失败",500);
                }
            }else{
                throw new HisException("密码长度至少位6位，不得超过10位",500);
            }
        }else{
            userInfo.setUserPassword(null);
        }
        int update = userInfoMapper.update(userInfo, new QueryWrapper<UserInfo>().eq("user_job_num", newUserForm.getUserJobNum()));
        if(update<=0) throw new HisException("员工信息更新失败",500);

        //删除旧的排班信息
        QueryWrapper<Schedule> wrapper = new QueryWrapper<>();
        wrapper.eq("schedule_user_id",newUserForm.getUserJobNum());
        int delete = scheduleMapper.delete(wrapper);
        if(delete<=0) throw new HisException("修改排班信息失败",500);

        //新建新的排班信息
        NewScheduleForm newScheduleForm = new NewScheduleForm();
        newScheduleForm.setScheduleUserId(newUserForm.getUserJobNum());
        newScheduleForm.setScheduleUserName(newUserForm.getUserName());
        newScheduleForm.setDepartmentId(newUserForm.getDepartmentId());
        newScheduleForm.setDisagnosisId(newUserForm.getDisagnosisId());
        boolean increaseSchedules = scheduleService.increaseSchedules(newScheduleForm);
        if(!increaseSchedules) throw new HisException("修改排班信息失败",500);

        return true;
    }

    /**
     * 获取当前登录员工的信息
     *
     * @param userJobNum 员工工号
     * @return 当前登录员工的信息
     */
    @Override
    public LoginUserInfo obtainUserInfo(Integer userJobNum) throws HisException {
        if(!StringToTrimUtil.StringToTrim(String.valueOf(userJobNum)) | StringToTrimUtil.StringToString(String.valueOf(userJobNum)).length()<5){
            throw new HisException("工号格式不对，请输入正确信息",500);
        }

        QueryWrapper<UserInfo> wrapper = new QueryWrapper<>();
        wrapper.eq("user_job_num",userJobNum);
        UserInfo userInfo = userInfoMapper.selectOne(wrapper);
        if(null == userInfo) throw new HisException("该工号不存在",500);
        return WebBeanUtils.copyObject(userInfo, LoginUserInfo.class);
    }

    /**
     * 根据工号或姓名模糊查询
     *
     * @param obtainInfo 查询条件
     * @return 员工信息
     */
    @Override
    public List<UserAllInfo> obtainByInfo(String obtainInfo) throws HisException {
        //判断字符是否为空
        if(null == obtainInfo) throw new HisException("请输入正确信息",500);
        if(!StringToTrimUtil.StringToTrim(obtainInfo)){
            throw new HisException("请输入正确信息",500);
        }

        //查询
        QueryWrapper<UserInfo> wrapper = new QueryWrapper<>();
        wrapper.like("user_job_num",obtainInfo).or().like("user_name",obtainInfo);
        List<UserInfo> userInfos = userInfoMapper.selectList(wrapper);
        if(null == userInfos | userInfos.size()==0) throw new HisException("该员工不存在",500);

        return WebBeanUtils.copyList(userInfos,UserAllInfo.class);
    }

    /**
     * 获取某页员工信息
     *
     * @param pagenum  页码
     * @param pagesize 每页数据量
     * @return 员工信息
     */
    @Override
    public PageInfo<UserAllInfo> obtainByPage(Integer pagenum, Integer pagesize) throws HisException {
        //参数校验
        if(!StringToTrimUtil.StringToTrim(String.valueOf(pagenum)) | !StringToTrimUtil.StringToTrim(String.valueOf(pagesize))){
            throw new HisException("请输入正确信息",500);
        }
        if(pagenum<1 || pagesize<1) throw new HisException("页码、数据量必须大于0",500);
        //查询
        Page<UserInfo> userInfoPage = new Page<>();
        userInfoPage.setCurrent(pagenum).setSize(pagesize);
        Page<UserInfo> needUserInfo = userInfoMapper.selectPage(userInfoPage, null);
        if(null == needUserInfo.getRecords()) throw new HisException("查询失败，未获取到相关信息",500);

        PageInfo<UserAllInfo> pageInfo = new PageInfo<>();
        pageInfo.setPageNum(needUserInfo.getCurrent());
        pageInfo.setPageSize(needUserInfo.getSize());
        pageInfo.setTotalPage(needUserInfo.getTotal());
        pageInfo.setRecord(WebBeanUtils.copyList(needUserInfo.getRecords(),UserAllInfo.class));

        return pageInfo;
    }

    /**
     * 根据科室、诊室获取员工信息
     *
     * @param userDepartment     科室名称
     * @param userDisagnosisRoom 诊室名称
     * @return 员工信息
     */
    @Override
    public UserByIdsInfo obtainByNames(String userDepartment, String userDisagnosisRoom) throws HisException {
        //参数校验
        if(null == userDepartment) throw new HisException("请输入正确信息",500);
        if(!StringToTrimUtil.StringToTrim(userDepartment)){
            throw new HisException("请输入正确信息",500);
        }

        //判断科室、诊室是否存在
        DepartmentInfo departmentInfo = departmentService.obtainByCondition(userDepartment);
        System.out.println(departmentInfo);
        if(null == departmentInfo | !departmentInfo.getDepartmentName().equals(userDepartment)) throw new HisException("该诊室信息有误",500);

        if(departmentInfo.getDepartmentState().equals("是")){
            if(null == userDisagnosisRoom) throw new HisException("该科室存在下属诊室，请确认诊室信息",500);
            if(!StringToTrimUtil.StringToTrim(userDisagnosisRoom)) throw new HisException("该科室存在下属诊室，请确认诊室信息",500);
            DisagnosisRoom disagnosisRoom = disagnosisRoomMapper.selectOne(new QueryWrapper<DisagnosisRoom>().eq("disagnosis_name", userDisagnosisRoom));
            if(null == disagnosisRoom | disagnosisRoom.getDepartmentId()!=departmentInfo.getDepartmentId()) throw new HisException("该诊室不存在",500);
        } else{
            if(null!=userDisagnosisRoom) {
                if(StringToTrimUtil.StringToTrim(userDisagnosisRoom))throw new HisException("该科室不存在诊室",500);
            }
        }

        //获取员工信息
        QueryWrapper<UserInfo> wrapper = new QueryWrapper<>();
        if(departmentInfo.getDepartmentState().equals("是")){
            wrapper.eq("user_department",userDepartment).eq("user_disagnosis_room",userDisagnosisRoom);
        }else{
            wrapper.eq("user_department",userDepartment);
        }
        List<UserInfo> userInfo = userInfoMapper.selectList(wrapper);
        if(null == userInfo) throw new HisException("该员工不存在",500);

        List<UserAllInfo> userAllInfos = WebBeanUtils.copyList(userInfo, UserAllInfo.class);
        System.out.println(userAllInfos);
        UserByIdsInfo userByIdsInfo = new UserByIdsInfo();
        userByIdsInfo.setUsers(userAllInfos);
        return userByIdsInfo;
    }

    /**
     * 注销员工
     *
     * @param userJobNum 注销员工的工号
     */
    @Override
    public boolean logoutUser(Integer userJobNum) throws HisException {
        if(!StringToTrimUtil.StringToTrim(String.valueOf(userJobNum))){
            throw new HisException("请输入正确信息",500);
        }
        //判断员工是否存在
        QueryWrapper<UserInfo> wrapper = new QueryWrapper<>();
        wrapper.eq("user_job_num",userJobNum);
        UserInfo userInfo = userInfoMapper.selectOne(wrapper);
        if(null == userInfo) throw new HisException("该员工不存在",500);

        //清除排班信息
        ArrayList<Integer> integers = new ArrayList<>();
        integers.add(userJobNum);
        boolean b = scheduleService.logoutSchedule(integers, userInfo.getDepartmentId(), userInfo.getDisagnosisId());
        if(!b) throw new HisException("排班信息清除失败",500);

        int delete = userInfoMapper.delete(wrapper);
        if(delete<=0) throw new HisException("注销失败",500);

        return true;
    }

    /**
     * 批量注销员工
     *
     * @param userJobNums 注销的员工工号
     */
    @Override
    public boolean logoutUsers(List<Integer> userJobNums) throws HisException {
        if(null == userJobNums | userJobNums.size()<=0) throw new HisException("请输入正确信息",500);
        //判断员工是否存在
        QueryWrapper<UserInfo> wrapper = new QueryWrapper<>();
        wrapper.in("user_job_num",userJobNums);
        List<UserInfo> userInfos = userInfoMapper.selectList(wrapper);
        if(userInfos.size()!=userJobNums.size()) throw new HisException("部分员工不存在，请确认信息是否正确",500);
        //清除排班信息
        boolean b = scheduleService.logoutSchedule(userJobNums, userInfos.get(0).getDepartmentId(), userInfos.get(0).getDisagnosisId());
        if(!b) throw new HisException("排班信息清除失败",500);

        int delete = userInfoMapper.delete(wrapper);
        if(delete<=0) throw new HisException("批量注销失败",500);

        return true;
    }

    /**
     * 员工登录
     *
     * @param userJobNum   员工工号
     * @param userPassword 登录密码
     * @return  员工信息
     */
    @Override
    public UserAllInfo loginUser(Integer userJobNum, String userPassword) throws HisException{
        if(!StringToTrimUtil.StringToTrim(userPassword) | !StringToTrimUtil.StringToTrim(String.valueOf(userJobNum))) throw new HisException("登录信息有误",500);
        if(userJobNum.toString().length()<5) throw new HisException("工号输入有误",500);
        if(StringToTrimUtil.StringToString(userPassword).length()<6 || StringToTrimUtil.StringToString(userPassword).length()>10) throw new HisException("密码长度不符合要求",500);
        String pattern = "^[a-zA-Z0-9]{5,10}";
        if(!Pattern.matches(pattern, userPassword)) throw new HisException("密码不能含有特殊字符",500);
        //判断员工是否存在
        UserInfo userInfo = userInfoMapper.selectOne(new QueryWrapper<UserInfo>().eq("user_job_num", userJobNum));
        if(null == userInfo) throw new HisException("用户不存在",500);
        boolean equals = true;
        try {
            equals = Md5Util.EncoderByMd5(userPassword).equals(userInfo.getUserPassword());
        } catch (NoSuchAlgorithmException e) {
            throw new HisException("解密失败",500);
        } catch (UnsupportedEncodingException e) {
            throw new HisException("解密失败",500);
        }

        if(!equals) throw new HisException("登录失败",500);
        return WebBeanUtils.copyObject(userInfo,UserAllInfo.class);
    }

    /**
     * 批量获取员工信息
     *
     * @param userJobNums 员工工号
     * @return 员工信息
     */
    @Override
    public List<UserByDayInfo> obtainUsers(List<Integer> userJobNums) throws HisException {
        if(userJobNums.size()<=0) { throw new HisException("请输入医生的工号",500); };
        //判断员工是否存在
        QueryWrapper<UserInfo> wrapper = new QueryWrapper<>();
        wrapper.in("user_job_num",userJobNums);
        List<UserInfo> userInfos = userInfoMapper.selectList(wrapper);
        if(null == userInfos){ throw new HisException("获取员工信息失败",500); }
        //删除
        List<UserByDayInfo> userByDayInfos = new ArrayList<>();
        for (int i = 0; i < userInfos.size(); i++) {
            UserByDayInfo userByDayInfo = new UserByDayInfo();
            userByDayInfo.setScheduleUserId(userInfos.get(i).getUserJobNum());
            userByDayInfo.setScheduleUserName(userInfos.get(i).getUserName());
            userByDayInfos.add(userByDayInfo);
        }
        System.out.println(userByDayInfos);
        return userByDayInfos;
    }
}
